#include "ui_city.h"

#include <assert.h>

#include "global.h"
#include "citymap.h"
#include "panel.h"
#include "palette.h"
#include "toolbar.h"


typedef struct {
	Panel* panel;
	Toolbar* toolbar;
	Citymap* citymap;
	int rel_x, rel_y;
	int last_x, last_y;
	SDL_Color color[256];
} UI;


static UI* initialize_ui()
{
	SDL_FillRect(screen, NULL, BLACK);
	SDL_Flip(screen);

	UI* ui = malloc(sizeof(UI));
	ui->citymap = new_citymap();
	ui->panel = new_panel();
	ui->toolbar = new_toolbar();
	ui->last_x = ui->last_y = ui->rel_x = ui->rel_y = 0;

	setup_palette(screen);
	load_default_palette(ui->color);

	return ui;
}


static void update_screen(UI* ui)
{
	// city
	SDL_SetClipRect(screen, &(SDL_Rect){ 0, 0, screen->w - ui->panel->w, 
			screen->h});
	SDL_BlitSurface(ui->citymap->sf, NULL, screen, 
			&(SDL_Rect) { ui->rel_x, ui->rel_y });
	SDL_SetClipRect(screen, NULL);

	// panel
	redraw_panel(ui->panel);

	// toolbar
	SDL_BlitSurface(ui->toolbar->sf, NULL, screen, &(SDL_Rect) {
			(screen->w/2 - ui->toolbar->sf->w/2), 0 });
	//SDL_UpdateRect(screen, (screen->w/2 - ui->toolbar->sf->w/2), 0,
	//		ui->toolbar->sf->w, BUTTON_W);
	
	SDL_Flip(screen);
}


static void mouse_button(UI* ui, SDL_MouseButtonEvent b)
{
	if(b.x > screen->w - ui->panel->w)
	{
		b.x -= (screen->w - ui->panel->w);
		panel_mouse_button(ui->panel, b);
	}
	else
	{
		if(toolbar_mouse_button(ui->toolbar, b))
			return;
	}
}


// The user dragged the map.
static void mouse_motion(UI* ui, SDL_MouseMotionEvent e)
{
	int xrel = e.x - ui->last_x;
	int yrel = e.y - ui->last_y;
                
	ui->last_x = e.x;
	ui->last_y = e.y;

	// right button pressed
	if(e.state & SDL_BUTTON(3))
	{
		if(ui->citymap->sf->w < screen->w)
			ui->rel_x = 0;
		else if(ui->rel_x + xrel > 0)
			ui->rel_x = 0;
		else if(ui->rel_x + xrel < (screen->w - ui->citymap->sf->w))
			ui->rel_x = (screen->w - ui->citymap->sf->w);
		else
			ui->rel_x += xrel;

		if(ui->citymap->sf->h < screen->h)
			ui->rel_y = 0;
		else if(ui->rel_y + yrel > 0)
			ui->rel_y = 0;
		else if(ui->rel_y + yrel < (screen->h - ui->citymap->sf->h))
			ui->rel_y = (screen->h - ui->citymap->sf->h);
		else
			ui->rel_y += yrel;
	}
}


static void main_loop(UI* ui)
{
	SDL_Event e;
	while(1)
	{
		Uint32 next = SDL_GetTicks() + (1000/60);

		// draw screen
		update_screen(ui);

		// parse events
		while(SDL_PollEvent(&e))
			switch(e.type)
			{
				case SDL_QUIT: case SDL_KEYDOWN:
					return;
				case SDL_MOUSEBUTTONDOWN:
					mouse_button(ui, e.button);
					break;
				case SDL_MOUSEMOTION:
					mouse_motion(ui, e.motion);
					break;
				case SDL_VIDEORESIZE:
					screen = SDL_SetVideoMode(e.resize.w, 
							e.resize.h, 8, 
							screen->flags);
					SDL_SetPalette(screen, 
							SDL_LOGPAL|SDL_PHYSPAL, 
							ui->color, 0, 255);
					ui->panel->dirty = true;
					break;
			}

		// process
		panel_process(ui->panel);

		// wait for next frame
		while(SDL_GetTicks() < next)
			SDL_Delay(1);
	}
}


void free_ui_city(UI* ui)
{
	if(!ui)
		return;

	free_panel(ui->panel);
	free_toolbar(ui->toolbar);
	free_citymap(ui->citymap);
	free(ui);
}


int show_ui_city()
{
	assert(city);

	UI* ui = initialize_ui();
	main_loop(ui);

	free_ui_city(ui);

	return -1;
}
